﻿using System;
using Medianamik.Core;
using SubSonic;
using Medianamik.Core.DAL.SubSonicDAL;
using System.Linq;
using System.Collections.Generic;
using SubSonicNode = Medianamik.Core.DAL.SubSonicDAL.Node;
using Medianamik.Core.DAL;
using System.Globalization;
using Medianamik.Core.Sugar;
using NUnit.Framework;
using Node = Medianamik.Core.Node;
using NodeInstance = Medianamik.Core.NodeInstance;
using Publication = Medianamik.Core.Publication;

namespace Tests.Integration_Medianamik
{
    [TestFixture]
    public class NodePropertyValueConversionTests
    {
        [Test]
        public void ConvertAllNodePropertyValueToNodeRevisions()
        {
            //NodePropertyValueConverter.ConvertAllNodePropertyValueToNodeRevisions();
        }

        [Test]
        public void GetNodesWithInvalidXmlCharacters()
        {
            var query = new Select().From(SubSonicNode.Schema);

            var allNodesCount = query.GetRecordCount();
            var nodeIDs = new HashSet<Guid>();
            var doubles = new HashSet<Guid>();
            var unresolvedNodeIDs = new HashSet<Guid>();
            const int bacthSize = 100;
            var nodeExceptions = new Dictionary<Node, IEnumerable<string>>();

            var j = 1;
            for (var i = 0; i < allNodesCount; i += bacthSize)
            {
                var batchNodeIDs = query.Paged(j, bacthSize)
                    .ExecuteAsCollection<NodeCollection>().ToList().Select(n => n.NodeId);

                foreach (var nodeID in batchNodeIDs)
                {
                    if (nodeIDs.Add(nodeID))
                    {
                        var node = NodeManager.GetNode(nodeID);

                        if (node == null)
                        {
                            unresolvedNodeIDs.Add(nodeID);
                        }
                        else
                        {
                            var publications = new HashSet<Publication>();

                            if (node.IsVersioned)
                            {
                                if (node.IsLanguageNeutral)
                                {
                                    node.Instances[""].Publications.ForEach(p => publications.Add(p));
                                }
                                else
                                {
                                    node.Instances.SelectMany(inst => inst.Publications).ForEach(
                                        p => publications.Add(p));
                                }
                            }

                            var exceptions = new HashSet<string>();

                            foreach (var publication in publications)
                            {
                                var exception = GetConversionException(publication, node);

                                if (exception != null)
                                    exceptions.Add(exception);
                            }

                            var exception2 = GetConversionException(null, node);

                            if (exception2 != null)
                                exceptions.Add(exception2);

                            if(exceptions.Any())
                            {
                                nodeExceptions.Add(node, exceptions);
                            }
                        }
                    }
                    else
                    {
                        doubles.Add(nodeID);
                    }
                }

                j++;
            }
        }

        private string GetConversionException(Publication publication, Node node)
        {
            var properties = new List<NodeProperty>();
            var revision = publication == null ? default(int?) : publication.Revision;

            if (node.IsLanguageNeutral)
            {
                properties.AddRange(NodePropertyValueConverter.GetPropertiesForRevision(node.Instances[""], revision));
            }
            else
            {
                properties.AddRange(node.Instances.SelectMany(i =>
                    NodePropertyValueConverter.GetPropertiesForRevision(i, revision)));
            }

            var liteProperties = new HashSet<NodePropertyValueLite>();

            foreach (var prop in properties)
            {
                if (prop as ManyToManyNodeProperty == null)
                    liteProperties.Add(new NodePropertyValueLite(prop));
            }

            try
            {
                liteProperties.SerializeProperties(null);
            }
            catch(Exception e)
            {
                return e.ToStringWithDetails();
            }

            return null;
        }
    }
}
